﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Xml.Serialization;
using System.Management;
namespace Powershell_ML
{

    public class Exchange_Information : PowerShell
    {
    //mailbox
        public void MDB_Update_Stats(List<MailboxDatabase> MDB )
        {
            try
            {
                if (MDB != null)
                {
                    foreach(MailboxDatabase mdb in MDB)
                    {
                        if(mdb.has_stats)
                        {
                            mdb.RefreshStats();
                        }
                    }
                }
            }
            catch (Exception) { }
        }
        public bool IsOdd(int Number)
        {
            return Number % 2 != 0;
        }
        public string Format_TimeSpan_Duration(TimeSpan Duration)
        {
            return "Day(s) : " + Duration.Days + Environment.NewLine +
                    "Hour(s) : " + Duration.Hours + Environment.NewLine +
                    "Minute(s) :" + Duration.Minutes + Environment.NewLine +
                    "Seconde(s) : " + Duration.Seconds;
                
        }
        public string Format_MB(string value)
        {
            return value + " MB";
        }

        public void Export_TMQUEUE(List<Queue> List)
        {
            if(List != null)
            {
                foreach (Queue mdb in List)
                {
                    System.Xml.Serialization.XmlSerializer writer = new XmlSerializer(typeof(Queue));
                    string topdir = Directory.GetCurrentDirectory();
                    topdir = topdir + @"\" + mdb.server + @"\" + mdb.short_queue_name + @"\";
                    string File_Name = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string path = topdir + File_Name + ".xml";
                    if (!Directory.Exists(topdir))
                    {
                        Directory.CreateDirectory(topdir);
                    }
                    System.IO.StreamWriter fwriter = new StreamWriter(path);

                    writer.Serialize(fwriter, mdb);
                    fwriter.Close();
                }
            }
        }

        //MailboxDatabase Helper
        public void MailboxDatabase_Export_Stats(List<MailboxDatabase> List)
        {
            if(List != null)
            {
                foreach (MailboxDatabase mdb in List)
                {
                    System.Xml.Serialization.XmlSerializer writer = new XmlSerializer(typeof(MailboxDatabase));
                    string topdir = Directory.GetCurrentDirectory();
                    topdir = topdir + @"\" + mdb.Server + @"\" + mdb.Name + @"\";
                    string File_Name = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string path = topdir + File_Name + ".xml";
                    if (!Directory.Exists(topdir))
                    {
                        Directory.CreateDirectory(topdir);
                    }
                    System.IO.StreamWriter fwriter = new StreamWriter(path);

                    writer.Serialize(fwriter, mdb);
                    fwriter.Close();
                }
            }

        }
        public bool Has_MDB_Stats(string serveur,string MDB)
        {
            if (MDB != null & serveur != null)
            {
                string topdir = Directory.GetCurrentDirectory();
                string[] Directory_Searcher = Directory.GetDirectories(topdir, "*", SearchOption.AllDirectories);
                foreach (string t in Directory_Searcher)
                {
                    DirectoryInfo Information = new DirectoryInfo(t);
                    if (Information.Name == MDB)
                    {
                        return true;
                    }
                }
            }
            return false;  
        }
        public int Compare_MBX_Size(MailboxDatabase MDBv0,MailboxDatabase MDBv01)
        {
           if(MDBv0 != null & MDBv01 != null)
            {
                int sourcesize = int.Parse(MDBv0.Size);
                int destsize = int.Parse(MDBv01.Size);
                return sourcesize - destsize;
            }
            return 0;
        }
        public  List<MailboxDatabase> Export_Stats(string serveur,string MDB)
        {
            List<MailboxDatabase> MDB_List = new List<MailboxDatabase>();
            if (MDB != null & serveur != null)
            {
                string topdir = Directory.GetCurrentDirectory();
                string[] Directory_Searcher = Directory.GetDirectories(topdir, "*", SearchOption.AllDirectories);
                foreach (string t in Directory_Searcher)
                {
                    DirectoryInfo Information = new DirectoryInfo(t);
                    if (Information.Name == MDB)
                    {
                        foreach (string file in Directory.GetFiles(t))
                        {
                            StreamReader reader = new StreamReader(file);
                            XmlSerializer Reader = new XmlSerializer(typeof(MailboxDatabase));
                            MailboxDatabase Temp = (MailboxDatabase)Reader.Deserialize(reader);
                            MDB_List.Add(Temp);
                        }
                    }
                    MDB_List = MDB_List.OrderBy(o => o.Collected_Date).ToList();
                }
            }
            return MDB_List;
        }
        public void Load_MDB_Stats(string serveur , string MDB)
        {
            if (MDB != null & serveur != null)
            {
                string topdir = Directory.GetCurrentDirectory();
                string[] Directory_Searcher = Directory.GetDirectories(topdir, "*", SearchOption.AllDirectories);
                foreach(string t in Directory_Searcher)
                {
                    DirectoryInfo Information = new DirectoryInfo(t);
                    if(Information.Name == MDB)
                    {
                        foreach(string file in Directory.GetFiles(t))
                        {
                            StreamReader reader = new StreamReader(file);
                            XmlSerializer Reader = new XmlSerializer(typeof(MailboxDatabase));
                            MailboxDatabase Temp = (MailboxDatabase)Reader.Deserialize(reader);
                        }
                    }
                }
            }

        }
        public Server Get_ExchangeServer_ByName(string server)
        {
            Command Get_Server = new Command("Get-ExchangeServer");
            Get_Server.Parameters.Add("Identity", server);

            PSObject Powershell_Output = Collectorsvc.Program.Runner.Execute_Command_Once(Get_Server);
            if(Powershell_Output != null)
            {
                return (new Server(Powershell_Output,false));
            }
            return null;
        }

        public Owa_VirtualDirectory Get_Owa_Vdir_ByServer(string server)
        {
            Command PowrShell = new System.Management.Automation.Runspaces.Command("Get-OwaVirtualDirectory");
            PowrShell.Parameters.Add("Server", server.ToString());

            PSObject Powershell_Output = Collectorsvc.Program.Runner.Execute_Command_Once(PowrShell);
            Owa_VirtualDirectory OWA = new Owa_VirtualDirectory();
            if (Powershell_Output != null)
            {
                OWA.AdminDisplayName = Powershell_Output.Properties["AdminDisplayName"].Value.ToString();
                OWA.BasicAuthentication = Powershell_Output.Properties["BasicAuthentication"].Value.ToString();
                OWA.ChangePasswordEnabled = Powershell_Output.Properties["ChangePasswordEnabled"].Value.ToString();
                OWA.CrossSiteRedirectType = Powershell_Output.Properties["CrossSiteRedirectType"].Value.ToString();
                OWA.DefaultDomain = Powershell_Output.Properties["DefaultDomain"].Value.ToString();
                OWA.DefaultTheme = Powershell_Output.Properties["DefaultTheme"].Value.ToString();
                OWA.DigestAuthentication = Powershell_Output.Properties["DigestAuthentication"].Value.ToString();
                OWA.DisplayName = Powershell_Output.Properties["DisplayName"].Value.ToString();
                OWA.DistinguishedName = Powershell_Output.Properties["DistinguishedName"].Value.ToString();
                OWA.Exchange2003Ur = Powershell_Output.Properties["Exchange2003Url"].Value.ToString();
                OWA.ExchangeVersion = Powershell_Output.Properties["ExchangeVersion"].Value.ToString();
                OWA.ExternalUrl = Powershell_Output.Properties["ExternalUrl"].Value.ToString();
                OWA.InternalUrl = Powershell_Output.Properties["InternalUrl"].Value.ToString();
                OWA.WebSite = Powershell_Output.Properties["WebSite"].Value.ToString();
                OWA.FailbackUrl = Powershell_Output.Properties["FailbackUrl"].Value.ToString();
                OWA.InstantMessagingEnabled = Powershell_Output.Properties["InstantMessagingEnabled"].Value.ToString();
                return OWA;
            }
            return OWA;

        }
        public List<Queue> TransportQueue_byServer(string server)
        {
            List<Queue> Transport_Q = new List<Queue>();
            Command Get_Mdb = new Command("Get-Queue");
            Get_Mdb.Parameters.Add("Server", server);

            List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Mdb);
            foreach (PSObject data_entry in Powershell_Output)
            {
                Transport_Q.Add(new Queue(data_entry));
            }
            return Transport_Q;
        }
        public List<MailboxDatabase> MailboxDatabase_ByServer(string Server)
        {
            List<MailboxDatabase> Mailbox_Dbs = new List<MailboxDatabase>();
            Command Get_Mdb = new Command("Get-MailboxDatabase");
            Get_Mdb.Parameters.Add("status");
            Get_Mdb.Parameters.Add("Server", Server);
            
            List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Mdb);
            foreach (PSObject data_entry in Powershell_Output)
            {
                Mailbox_Dbs.Add(new MailboxDatabase(data_entry));
            }
            return Mailbox_Dbs;
        }
        public List<Queue> Get_Queue(Server Exchange)
        {
            List<Queue> List = new List<Queue>();
            if(Exchange != null)
            {
                Command Get_Queue = new Command("Get-Queue");
                Get_Queue.Parameters.Add("Server", Exchange.Name);
                List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Queue);
                if (Powershell_Output.Count > 0)
                {
                    foreach (PSObject Object in Powershell_Output)
                    {
                        List.Add(new Queue(Object));
                    }
                }
                return List;
            }
            return null;
        }
        public List<Tracking> Get_Tracking(Server Exchange)
        {
            List<Tracking> List = new List<Tracking>();
            if (Exchange != null)
            {
                Command Get_Track = new Command("Get-MessageTrackingLog");
                Get_Track.Parameters.Add("Server", Exchange.Name);
                Get_Track.Parameters.Add("ResultSize", "Unlimited");
                List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Track);
                if (Powershell_Output.Count > 0)
                {
                    foreach (PSObject Object in Powershell_Output)
                    {
                        List.Add(new Tracking(Object));
                    }
                }
                return List;
            }
            return null;
        }
        public  Ad_Site Get_Adsite(Server Exchange,string site)
        {
            if(Exchange != null)
            {
                Command Get_Site = new Command("Get-AdSite");
                Get_Site.Parameters.Add("Identity", site);
                PSObject Powershell_Output = Collectorsvc.Program.Runner.Execute_Command_Once(Get_Site);
                if(Powershell_Output != null)
                {
                    Ad_Site Site = new Ad_Site();
                    Site.AdminDisplayName = Powershell_Output.Properties["Name"].Value.ToString();
                    Site.HubSiteEnabled = bool.Parse(Powershell_Output.Properties["HubSiteEnabled"].Value.ToString());
                    Site.PartnerID = int.Parse(Powershell_Output.Properties["PartnerID"].Value.ToString());
                    Site.WhenCreated = (DateTime)Powershell_Output.Properties["WhenCreated"].Value;
                    Site.WhenUpdated = (DateTime)Powershell_Output.Properties["WhenChangedUTC"].Value;
                    Site.DN = Powershell_Output.Properties["DistinguishedName"].Value.ToString();
                    return Site;   
                }
            }
            return new Ad_Site();
        }
        public  Version Exchange_Version(PSObject ExchangeServer)
        {
            try
            {
                string ExchangeVersion = ExchangeServer.Properties["AdminDisplayVersion"].Value.ToString();
                if (ExchangeVersion != null)
                {
                    if (ExchangeVersion.Contains("8."))
                    {
                        return Version.Exchange_2007;
                    }
                    if (ExchangeVersion.Contains("14."))
                    {
                        return Version.Exchange_2010;
                    }
                    if (ExchangeVersion.Contains("15."))
                    {
                        return Version.Exchange_2013;
                    }
                    if (ExchangeVersion.Contains("16."))
                    {
                        return Version.Exchange_2016;
                    }
                    else
                    {
                        return Version.Unknown;
                    }

                }
                return Version.Unknown;
            }
            catch{ return Version.Unknown; }
        }
        public int MailboxCount_ByDatabase(string MailboxDatabase)
        {
            Command Get_Mdb = new Command("Get-Mailbox");
            Get_Mdb.Parameters.Add("Database", MailboxDatabase);
            List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Mdb);
            return Powershell_Output.Count;
        }
        public int MDB_Lowest_Size
        {
            set;get;
        }

        public string Between(string Text, string FirstString, string LastString)
        {
            string STR = Text;
            string STRFirst = FirstString;
            string STRLast = LastString;
            string FinalString;
            string TempString;

            int Pos1 = STR.IndexOf(FirstString) + FirstString.Length;
            int Pos2 = STR.IndexOf(LastString);
            FinalString = STR.Substring(Pos1, Pos2 - Pos1);
            return FinalString;
        }

        public bool isMailbox(string server)
        {
            Command Get_Mdb = new Command("Get-ExchangeServer");
            Get_Mdb.Parameters.Add("Identity", server);
            PSObject Powershell_Output = Collectorsvc.Program.Runner.Execute_Command_Once(Get_Mdb);
            return (bool)Powershell_Output.Properties["IsMailboxServer"].Value;
        }
        public bool IsTransport(string server)
        {
            Command Get_Mdb = new Command("Get-ExchangeServer");
            Get_Mdb.Parameters.Add("Identity", server);
            PSObject Powershell_Output = Collectorsvc.Program.Runner.Execute_Command_Once(Get_Mdb);
            return (bool)Powershell_Output.Properties["IsHubTransportServer"].Value;
        }

        public List<Mailbox> Mailbox_ByServer(string Server)
        {
            List<Mailbox> Mailbox_Dbs = new List<Mailbox>();
            Command Get_Mdb = new Command("Get-Mailbox");
            Get_Mdb.Parameters.Add("Server", Server);
            List<PSObject> Powershell_Output = Collectorsvc.Program.Runner.Execute_Command(Get_Mdb);
            foreach (PSObject data_entry in Powershell_Output)
            {
                Mailbox_Dbs.Add(new Mailbox(data_entry));
            }
            return Mailbox_Dbs;
        }
        public List<Mailbox> Mailbox_Load_Stats(Mailbox Mailbox)
        {
            List<Mailbox> MDB_List = new List<Mailbox>();
            if (Mailbox != null)
            {
                string topdir = Directory.GetCurrentDirectory();
                topdir = topdir + @"\" + "Mailbox" + @"\" + Mailbox.GUID + @"\";
                string[] Directory_Searcher = Directory.GetFiles(topdir, "*", SearchOption.AllDirectories);
                foreach (string t in Directory_Searcher)
                {
                            StreamReader reader = new StreamReader(t);
                            XmlSerializer Reader = new XmlSerializer(typeof(Mailbox));
                            Mailbox Temp = (Mailbox)Reader.Deserialize(reader);
                            MDB_List.Add(Temp);
                }
                MDB_List = MDB_List.OrderBy(o => o.Collected_Date).ToList();
            }
            return MDB_List;

        }
        public bool Mailbox_Has_Stats(Mailbox Mailbox)
        {
            if (Mailbox != null)
            {

                string topdir = Directory.GetCurrentDirectory();
                topdir = topdir + @"\" + "Mailbox" + @"\" + Mailbox.GUID + @"\";
                if(Directory.Exists(topdir))
                { 
                        return true;
                }
            }
            return false;
        }
        public void Mailbox_Export_Stats(List<Mailbox> List)
        {
            if (List != null)
            {
                List.ToList().ForEach(x =>
                {
                    System.Xml.Serialization.XmlSerializer writer = new XmlSerializer(typeof(Mailbox));
                    string topdir = Directory.GetCurrentDirectory();
                    topdir = topdir + @"\" + "Mailbox" + @"\" + x.GUID + @"\";
                    string File_Name = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string path = topdir + File_Name + ".xml";
                    if (!Directory.Exists(topdir))
                    {
                        Directory.CreateDirectory(topdir);
                    }
                    System.IO.StreamWriter fwriter = new StreamWriter(path);

                    writer.Serialize(fwriter, x);
                    fwriter.Close();

                });
            }

        }
        public void Mailbox_Export_Stat(Mailbox mailbox)
        {
            if (mailbox != null)
            {
                    System.Xml.Serialization.XmlSerializer writer = new XmlSerializer(typeof(Mailbox));
                    string topdir = Directory.GetCurrentDirectory();
                    topdir = topdir + @"\" + "Mailbox" + @"\" + mailbox.GUID + @"\";
                    string File_Name = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string path = topdir + File_Name + ".xml";
                    if (!Directory.Exists(topdir))
                    {
                        Directory.CreateDirectory(topdir);
                    }
                    System.IO.StreamWriter fwriter = new StreamWriter(path);

                    writer.Serialize(fwriter, mailbox);
                    fwriter.Close();
            }
        }

        [XmlIgnoreAttribute]
        public string Informations = "test";
        #region "Helper Structure & Object Constructor"
        public List<ICollection> Property_Collection(PSObject Obj)
        {
            List<ICollection> Property_Data = new List<ICollection>();
            Obj.Properties.ToList().ForEach(x =>
            {
                if (x.Value is ICollection)
                {
                    ICollection temp = (ICollection)x.Value;

                    Property_Data.Add(temp);
                }
            });
            return Property_Data;
        }
        #endregion
        #region "Security Helper"
        SecureString convertToSecureString(string strPassword)
        {
            var secureStr = new SecureString();
            if (strPassword.Length > 0)
            {
                foreach (var c in strPassword.ToCharArray()) secureStr.AppendChar(c);
            }
            return secureStr;
        }
        String SecureStringToString(SecureString value)
        {
            IntPtr valuePtr = IntPtr.Zero;
            try
            {
                valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
                return Marshal.PtrToStringUni(valuePtr);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
            }
        }
        #endregion
        #region "Generic Method for Object Parsing
        public string GetPropertyName<T>(Expression<Func<T>> property)
        {
            var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
            if (propertyInfo == null)
            {
                throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
            }
            return propertyInfo.Name;
        }
        public string Extract_Property(List<PSPropertyInfo> Database, string Property)
        {
            var Data = from x in Database
                       where x.Name == Property
                       select x.Value;
            return Data.ToString();
        }
        public string Extract_String_Property(List<PSPropertyInfo> Datatable, string propertyfilter)
        {
            try
            {
                foreach (PSPropertyInfo found in Datatable)
                {
                    if (found.TypeNameOfValue != null & found.Value != null & found.Name != null)
                    {
                        if (found.Name.ToString() == propertyfilter)
                        {
                            return found.Value.ToString();
                        }
                    }
                }
                return string.Empty;
            }

            catch (Exception) { return string.Empty; }
        }
        #endregion


    }
}
